# -*- coding: utf-8 -*-

import jwt

from pydantic import BaseModel

from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer

from jwt.exceptions import InvalidTokenError

from datetime import datetime, timedelta

from config.env import JwtConfig

oauth2_scheme = OAuth2PasswordBearer(tokenUrl=JwtConfig.jwt_oauth2_login_url)

class Token(BaseModel):
    access_token: str
    refresh_token: str
    token_type: str
def create_token(data: dict, expires_delta: int | None = None):
    '''
    创建token
    '''
    to_encode_data = data.copy()
    if expires_delta:
        expire = datetime.utcnow() + timedelta(minutes=expires_delta)
    else:
        expire = datetime.utcnow() + timedelta(minutes=15)
    to_encode_data.update({"exp": expire})
    return jwt.encode(to_encode_data, JwtConfig.jwt_secret_key, algorithm=JwtConfig.jwt_algorithm)


def create_access_token(data: dict):
    '''
    创建 access token
    '''
    return create_token(data, expires_delta=JwtConfig.jwt_access_token_expires)

def create_refresh_token(data: dict):
    '''
    创建 refresh token
    '''
    return create_token(data, expires_delta=JwtConfig.jwt_refresh_token_expires)

async def get_token_data(token: str = Depends(oauth2_scheme)):
    '''
    获取token数据
    '''
    try:
        return jwt.decode(token, JwtConfig.jwt_secret_key, algorithms=[JwtConfig.jwt_algorithm])
    except jwt.ExpiredSignatureError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="凭证已证过期",
            headers={"WWW-Authenticate": f"Bearer {token}"},
        )

    except jwt.InvalidTokenError:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="无效凭证",
            headers={"WWW-Authenticate": f"Bearer {token}"},
        )

    except (PyJWTError, ValidationError):
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="无效凭证",
            headers={"WWW-Authenticate": f"Bearer {token}"},
        )
